
#ifndef RTACCEPTORTHREADPROXY_H
#define RTACCEPTORTHREADPROXY_H

#include "RtReferenceControl.h"
#include "RtConnectionInterface.h"
#include "RtAcceptorConnectorSinkThreadProxy.h"

class /*RT_API_EXPORT*/ CRtAcceptorThreadProxy
	: public IRtAcceptor
	, public CRtReferenceControlMutilThread 
	, public CRtAcceptorConnectorSinkThreadProxyT<CRtAcceptorThreadProxy>
	, public CRtStopFlag
{
public:
	CRtAcceptorThreadProxy(
		CRtConnectionManager::CType aType,
		CRtThread *aThreadNetwork = NULL,
		CRtThread *aThreadUser = NULL);
	
	virtual ~CRtAcceptorThreadProxy();
	
	// interface IRtReferenceControl
	virtual DWORD AddReference();
	virtual DWORD ReleaseReference();
	virtual void OnReferenceDestory();

	// interface IRtAcceptorConnectorId
	virtual BOOL IsConnector();

	// interface IRtAcceptor
	virtual RtResult StartListen(
		IRtAcceptorConnectorSink *aSink,
		const CRtInetAddr &aAddrListen);

	virtual RtResult StopListen(RtResult aReason);

	IRtAcceptorConnectorId* GetActualAcceptorConnectorId()
	{
		return m_pAcceptorActual.Get();
	}

	// we have to overlaod this function because class 
	// CRtAcceptorConnectorSinkThreadProxyT<CRtAcceptorBase> will invoke it.
	void SetStopFlag() { }

private:
	CRtThread *m_pThreadUser;
	CRtThread *m_pThreadNetwork;
	CRtAutoPtr<IRtAcceptor> m_pAcceptorActual;
	CRtConnectionManager::CType m_Type;

	friend class CEventStartListen;
	friend class CEventStopListen;

	friend class CRtAcceptorConnectorSinkThreadProxyT<CRtAcceptorThreadProxy>;
	friend class CEventOnConnectIndication<CRtAcceptorThreadProxy>;
};

	class CEventStartListen : public IRtEvent
	{
	public:
		CEventStartListen(
			CRtAcceptorThreadProxy *aThreadProxy,
			IRtAcceptorConnectorSink *aSink,
			const CRtInetAddr &aAddrListen);

		virtual ~CEventStartListen();

		virtual RtResult OnEventFire();

	private:
		CRtAutoPtr<CRtAcceptorThreadProxy> m_pOwnerThreadProxy;
		IRtAcceptorConnectorSink *m_pSink;
		CRtInetAddr m_addrListen;
	};

	class CEventStopListen : public IRtEvent
	{
	public:
		CEventStopListen(
			CRtAcceptorThreadProxy *aConnectorThreadProxy,
			RtResult aReason);

		virtual ~CEventStopListen();

		virtual RtResult OnEventFire();

	private:
		CRtAutoPtr<CRtAcceptorThreadProxy> m_pOwnerThreadProxy;
		RtResult m_Reason;
	};


#endif // !RTACCEPTORTHREADPROXY_H
